package com.wangjiacai.utils.utils;

import org.springframework.beans.BeanUtils;
import org.springframework.util.StringUtils;

import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;


public class BeanUtil {

     public static<T> T getStaticPropertyValue(Class tClass,String property,Class<T> returnType){
         try {
             Field field = tClass.getDeclaredField(property);
             if(Modifier.isStatic(field.getModifiers())){
                 return (T) field.get(tClass);
             }
         } catch (Exception e) {
             e.printStackTrace();
             throw new RuntimeException(e);
         }
         return null;
     }
    /**
     * 获取对象中所有属性
     * @param source
     * @return
     */
    public static String[] getPropertyNames (Object source) {
        PropertyDescriptor[] pds = BeanUtils.getPropertyDescriptors(source.getClass());

        Set<String> emptyNames = new HashSet<String>();
        for(PropertyDescriptor pd : pds) {
            emptyNames.add(pd.getName());
        }
        String[] result = new String[emptyNames.size()];
        return emptyNames.toArray(result);
    }


    /*
     * @Description:  获取对象中属性值
     * @Param: [object, property]
     * @return: java.lang.Object
     * @Author: wangjiacai
     * @Date: 2018/8/8
     */
    public static<T> T getPropertyValue(Object object,String property,Class<T> returnType){
        Class obClass=object.getClass();
        PropertyDescriptor pds;
        try {
            pds = new PropertyDescriptor(property,obClass);
            Method read=pds.getReadMethod();
            return (T) read.invoke(object);
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }

    /**
     * 获取对象中空值属性
     * @param source
     * @return
     */
    public static String[] getNullPropertyNames (Object source) {
        PropertyDescriptor[] pds = BeanUtils.getPropertyDescriptors(source.getClass());
        
        Set<String> emptyNames = new HashSet<String>();
        for(PropertyDescriptor pd : pds) {
            if(pd.getName().equals("class")) continue;
            Object srcValue = getPropertyValue(source,pd.getName(),Object.class);
            if (srcValue == null) emptyNames.add(pd.getName());
        }
        String[] result = new String[emptyNames.size()];
        return emptyNames.toArray(result);
    }

    /**
     * 获取对象中空值属性和空字符串属性
     * @param source
     * @return
     */
    public static String[] getEmptyPropertyNames (Object source) {
        PropertyDescriptor[] pds = BeanUtils.getPropertyDescriptors(source.getClass());

        Set<String> emptyNames = new HashSet<String>();
        for(PropertyDescriptor pd : pds) {
            if(pd.getName().equals("class")) continue;
            Object srcValue = getPropertyValue(source,pd.getName(),Object.class);
            if (srcValue == null) emptyNames.add(pd.getName());
            if (srcValue instanceof String&& StringUtils.isEmpty(srcValue)){
                emptyNames.add(pd.getName());
            }
        }
        String[] result = new String[emptyNames.size()];
        return emptyNames.toArray(result);
    }

    /**
     * 获取对象中非空值属性和非空字符串属性
     * @param source
     * @return
     */
    public static String[]  getNotEmptyPropertyNames (Object source) {
        PropertyDescriptor[] pds = BeanUtils.getPropertyDescriptors(source.getClass());

        Set<String> emptyNames = new HashSet<String>();
        for(PropertyDescriptor pd : pds) {
            Object srcValue = getPropertyValue(source,pd.getName(),Object.class);
            if (srcValue instanceof String&&!StringUtils.isEmpty(srcValue)){
                emptyNames.add(pd.getName());
            }
            if (srcValue != null) emptyNames.add(pd.getName());
        }
        String[] result = new String[emptyNames.size()];
        return emptyNames.toArray(result);
    }




    /**
     * 设置对象中属性值
     * @param source
     * @return
     */
    public static void setValueByPropertyName(Object source,String property,Object value){
        Class obClass=source.getClass();
        PropertyDescriptor pds= null;
        try {
            pds = new PropertyDescriptor(property,obClass);
            Method write=pds.getWriteMethod();
            write.invoke(source,value);
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }

    /*
     * @Description: 把source对象非null属性复制到target
     * @Param:
     * @return:
     * @Author: wangjiacai
     * @Date: 2018/8/8
     */
    public static void copyPropertiesIgnoreNull(Object source, Object target){
        BeanUtils.copyProperties(source, target, getNullPropertyNames(source));
    }

    /*
     * @Description: 把source对象非空属性复制到target
     * @Param:
     * @return:
     * @Author: wangjiacai
     * @Date: 2018/8/8
     */
    public static void copyPropertiesIgnoreEmpty(Object source, Object target){
        BeanUtils.copyProperties(source, target, getEmptyPropertyNames(source));
    }

    /*
     * @Description: 把source对象属性(包含控制)复制到target
     * @Param:
     * @return:
     * @Author: wangjiacai
     * @Date: 2018/8/8
     */
    public static void copyProperties(Object source, Object target){
        BeanUtils.copyProperties(source, target);
    }

    /*
     * @Description: 对象属性转换成Map
     * @Param:
     * @return:
     * @Author: wangjiacai
     * @Date: 2018/8/8
     */
    public static Map<String,Object> objectToMap(Object object){
        Map<String,Object> map=new HashMap<>();
        if(object==null) return map;
        PropertyDescriptor[] pds = BeanUtils.getPropertyDescriptors(object.getClass());
        for(PropertyDescriptor pd : pds) {
            Object srcValue = getPropertyValue(object,pd.getName(),Object.class);
            map.put(pd.getName(),srcValue);
        }
        return map;
    }

}
